package uz.rt.utils;

/**
 * The class creates a generic object that can hold two other objects. The class implements a Comparable interface
 * making the class ready for collection based sorting.
 *
 * @param <K> Datatype for the first variable
 * @param <V> Datatype for the second variable
 */
public class Pair<K extends Comparable, V extends Comparable> implements Comparable<Pair<K, V>>
{
// ------------------------------ FIELDS ------------------------------

    /** First variable */
    private K x;
    /** Second variable */
    private V y;

// --------------------------- CONSTRUCTORS ---------------------------

    /** Constructor intitialises the first and second variable to null */
    public Pair()
    {
        x = null;
        y = null;
    }

    /**
     * Constructor initialises the first and second variable based on its arguments
     *
     * @param x first variable
     * @param y second variable
     */
    public Pair(final K x, final V y)
    {
        setX(x);
        setY(y);
    }

// --------------------- GETTER / SETTER METHODS ---------------------

    /**
     * Get the first variable
     *
     * @return First variable
     */
    public K getX()
    {
        return x;
    }

    /**
     * Set the first variable
     *
     * @param x first variable
     */
    public void setX(K x)
    {
        this.x = x;
    }

    /**
     * Get the second variable
     *
     * @return Second variable
     */
    public V getY()
    {
        return y;
    }

    /**
     * Set the second variable
     *
     * @param y second variable
     */
    public void setY(V y)
    {
        this.y = y;
    }

// ------------------------ CANONICAL METHODS ------------------------

    @Override
    public boolean equals(Object o)
    {
        if (!(o instanceof Pair)) return false;
        if (this == o) return true;

        Pair pair = (Pair) o;

        return !(x != null ? !x.equals(pair.x) : pair.x != null) && !(y != null ? !y.equals(pair.y) : pair.y != null);
    }

    @Override
    public int hashCode()
    {
        int result = x.hashCode();
        result = 31 * result + y.hashCode();
        return result;
    }

    @Override
    public String toString()
    {
        return String.valueOf(x) + ", " + String.valueOf(y);
    }

// ------------------------ INTERFACE METHODS ------------------------


// --------------------- Interface Comparable ---------------------

    public int compareTo(Pair<K, V> pair) throws ClassCastException
    {
        //noinspection unchecked,unchecked,unchecked
        return x.compareTo(pair.x);
    }
}
